package cn.yy.logreportmanager.service.impl;

import cn.yy.logreportmanager.dto.common.Response;
import cn.yy.logreportmanager.dto.common.ResponseBean;
import cn.yy.logreportmanager.dto.relation.*;
import cn.yy.logreportmanager.entity.*;
import cn.yy.logreportmanager.mapper.*;
import cn.yy.logreportmanager.service.RelationService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class RelationServiceImpl implements RelationService {
    @Autowired
    EmployeeMapper employeeMapper;
    @Autowired
    DepartmentMapper departmentMapper;
    @Autowired
    CustomerMapper customerMapper;
    @Autowired
    ContactMapper contactMapper;
    @Autowired
    CustomerRelatedMapper customerRelatedMapper;
    @Autowired
    CCustomerRelationMapper cCustomerRelationMapper;

    private static class CondMapKey{
        public final static String cusName = "cusName";
        public final static String cusID = "cusID";
        public final static String deptID = "deptID";
        public final static String cusMgrID = "cusMgrID";
    }
    @Override
    public ResponseBean<?> conditionQuery(Map<String, String> condMap) {
        ResponseBean<?> checkResp = condQueryArgCheck(condMap);
        if (checkResp != null) return checkResp;

        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
        if (condMap.containsKey(CondMapKey.cusName)){
            queryWrapper.and(qw -> qw.like(Customer::getCusName,"%"+condMap.get(CondMapKey.cusName)+"%"));
        }
        if (condMap.containsKey(CondMapKey.deptID)){
            queryWrapper.and(qw -> qw.eq(Customer::getCusSalesDeptId, condMap.get(CondMapKey.deptID)));
        }
        if (condMap.containsKey(CondMapKey.cusMgrID)){
            queryWrapper.and(qw -> qw.eq(Customer::getCusCustomerManagerId, condMap.get(CondMapKey.cusMgrID)));
        }
        if (condMap.containsKey(CondMapKey.cusID)){
            queryWrapper.and(qw -> qw.eq(Customer::getCusId, condMap.get(CondMapKey.cusID)));
        }

        List<Customer> customers = customerMapper.selectList(queryWrapper);

        return wrapListAsResponse(customers);
    }

    private ResponseBean<?> condQueryArgCheck(Map<String, String> condMap){
        Set<String> keys = new HashSet<>(condMap.keySet());
        for (String key:keys){
            if (condMap.get(key) == null){
                condMap.remove(key);
            }
        }
        if (condMap.containsKey(CondMapKey.cusMgrID) && condMap.containsKey(CondMapKey.deptID)){
            Employee employee = employeeMapper.selectById(condMap.get(CondMapKey.cusMgrID));
            if (employee == null){
                return Response.simpleErr("Employee ID Not Found: " +
                        condMap.get(CondMapKey.cusMgrID),"");
            }
            Department department = departmentMapper.selectById(employee.getEmpDeptId());
            if (department == null) {
                return Response.simpleErr(
                        "Employee ("+ condMap.get(CondMapKey.cusMgrID)+") Not Found " +
                                "in Department ("+ condMap.get(CondMapKey.deptID)+")","");
            }
        }
        return null;
    }

    private ResponseBean<?> wrapListAsResponse(List<Customer> customers){
        List<CusEntry> entries = customers.stream().map(customer -> {
            CusEntry cusEntry = new CusEntry();
            cusEntry.setCusID(customer.getCusId());
            cusEntry.setCusMgrID(customer.getCusCustomerManagerId());
            cusEntry.setDeptID(customer.getCusSalesDeptId());
            cusEntry.setCusName(customer.getCusName());
            cusEntry.setContacts(contactMapper.selectList(
                    new LambdaQueryWrapper<Contact>()
                            .eq(Contact::getConCustomerId, customer.getCusId())
            ));

            Employee employee = employeeMapper.selectById(customer.getCusCustomerManagerId());
            cusEntry.setCusMgrName(employee.getEmpName());

            List<RelCusEntry> relCusEntries = customerRelatedMapper.selectList(
                    new LambdaQueryWrapper<CustomerRelated>()
                            .eq(CustomerRelated::getCusrelCusId, customer.getCusId())
            ).stream().map(customerRelated -> {
                RelCusEntry entry = new RelCusEntry();
                Customer relatedCus = customerMapper
                        .selectById(customerRelated.getCusrelCusRelatedCusId());
                entry.setRelCusID(customerRelated.getCusrelCusRelatedCusId());
                entry.setRelCusName(relatedCus.getCusName());
                entry.setRelDetail(cCustomerRelationMapper.selectById(
                        customerRelated.getCusrelRelation()
                ).getCusrelRelationName());
                return entry;
            }).collect(Collectors.toList());
            cusEntry.setRelCustomers(relCusEntries);

            return cusEntry;
        }).collect(Collectors.toList());

        CusRelationBody body = new CusRelationBody();
        body.setEntries(entries);
        ResponseBean<CusRelationBody> responseBean = new ResponseBean<>();
        responseBean.setBody(body);
        responseBean.setStatus(Response.STATE_OK);

        return responseBean;
    }
}
